package com.gitee.wsl.compose.modifier.draw

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

/**
 * Draws a horizontal divider at the bottom of the composable.
 *
 * A divider is a thin line that groups content in lists and layouts.
 *
 * ![Dividers image](https://developer.android.com/images/reference/androidx/compose/material/dividers.png)
 *
 * @param color The color of the divider line.
 * @param thickness The thickness of the divider line. By default, 1 dp is used. Using [Dp.Hairline]
 *                  will produce a single pixel divider regardless of screen density.
 * @param indent The offset of the line from the left and right edges of the composable. No offset is
 *               used by default.
 * @return A modified [Modifier] that draws a horizontal divider at the bottom of the composable.
 *
 * Usage example:
 * ```
 * Column {
 *     // content here
 *     Spacer(modifier = Modifier.height(16.dp))
 *     Text("Section 1", modifier = Modifier.drawHorizontalDivider(Color.Gray))
 *     // more content here
 * }
 * ```
 *
 * @since 1.0.0
 * @see [drawVerticalDivider]
 * @see [Divider]
 * @see [DividerVertical]
 */
fun Modifier.drawHorizontalDivider(
    color: Color,
    thickness: Dp = 1.dp,
    indent: PaddingValues = PaddingValues(0.dp)
) = drawWithContent {

    // calculate the respective indents.
    val startIndentPx = indent.calculateStartPadding(layoutDirection).toPx()
    val endIndentPx = indent.calculateEndPadding(layoutDirection = layoutDirection).toPx()
    val topIndentPx = indent.calculateTopPadding().toPx()
    val bottomIndentPx = indent.calculateBottomPadding().toPx()

    // width and height of the composable UI element.
    val (width, height) = size

    // constructs offsets of the divider.
    val start = Offset(
        startIndentPx,

        // top will get added and bottom will get subtracted.
        height + topIndentPx - bottomIndentPx
    )

    val end = Offset(
        width - endIndentPx,
        height + topIndentPx - bottomIndentPx
    )

    val thicknessPx = thickness.toPx()

    drawContent()
    drawLine(
        color.copy(DividerAlpha),
        strokeWidth = thicknessPx,
        start = start,
        end = end
    )
}

private const val DividerAlpha = 0.12f

/**
 * Draws vertical [Divider] at the end of the composable
 * @see drawHorizontalDivider
 */
fun Modifier.drawVerticalDivider(
    color: Color,
    thickness: Dp = 1.dp,
    indent: PaddingValues = PaddingValues(0.dp)
) = drawWithContent {

    // calculate the respective indents.
    val startIndentPx = indent.calculateStartPadding(layoutDirection).toPx()
    val endIndentPx = indent.calculateEndPadding(layoutDirection = layoutDirection).toPx()
    val topIndentPx = indent.calculateTopPadding().toPx()
    val bottomIndentPx = indent.calculateBottomPadding().toPx()

    // width and height of the composable UI element.
    val (width, height) = size

    // constructs offsets of the divider.
    val start = Offset(
        width + startIndentPx,

        // top will get added and bottom will get subtracted.
        topIndentPx
    )

    val end = Offset(
        width - endIndentPx,
        height - bottomIndentPx
    )

    val thicknessPx = thickness.toPx()

    drawContent()
    drawLine(
        color.copy(DividerAlpha),
        strokeWidth = thicknessPx,
        start = start,
        end = end
    )
}